<template>
  <el-container id="backstageManagerPage">
    <el-header id="appTopHeader">
      <div id="appLogo">
        <img src="@/assets/image/logo.png" alt="">
      </div>
      <el-menu id="topNavMenu" :default-active="topMenuActiveIndex" class="el-menu-demo" mode="horizontal" @select="handleTopMenuSelect" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
        <el-submenu index="1">
          <template slot="title">菜单一</template>
          <el-menu-item index="1-1">选项1</el-menu-item>
          <el-menu-item index="1-2">选项2</el-menu-item>
          <el-submenu index="1-3">
            <template slot="title">选项3</template>
            <el-menu-item index="1-3-1">选项3-1</el-menu-item>
            <el-menu-item index="1-3-2">选项3-2</el-menu-item>
          </el-submenu>
        </el-submenu>
        <el-submenu index="2">
          <template slot="title">切换语言</template>
          <el-menu-item index="2-1">简体</el-menu-item>
          <el-menu-item index="2-2">繁体</el-menu-item>
        </el-submenu>
        <el-submenu index="3">
          <template slot="title">切换主题</template>
          <el-menu-item index="3-1">主题一</el-menu-item>
          <el-menu-item index="3-2">主题二</el-menu-item>
        </el-submenu>
      </el-menu>
    </el-header>
    <el-container>
      <el-aside id="leftNavMenu" style="width: 200px;">
        <!-- vue中要递归生成菜单，要用主文件引用子组件，子组件去递归才能实现。单单一个页面是无法递归的 -->
        <Menu :menuList="treeFormatLeftMenu" :activeMenuId="leftMenuActiveIndex" @select="handleLeftMenuSelect"></Menu>
      </el-aside>
      <el-main id="centerDiv">
        <!-- 面包屑 -->
        <el-breadcrumb separator="/" id="centerBreadcrumb">
          <el-breadcrumb-item v-for="(item, index) in breadcrumbList" :key="index">{{item.name}}</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 页面tabList -->
        <el-tabs v-model="activeTabId" type="border-card" id="centerTab" closable @tab-remove="handleRemoveTab" @contextmenu.prevent.native="openTabContextMenu($event)">
          <el-tab-pane v-for="(menu, index) in tabList" :key="menu.id + index" :label="menu.name" :name="menu.id">
            <template v-if="!menu.reloading">
              <!-- 外链 -->
              <iframe v-if="menu.url" :src="menu.url"></iframe>
              <!-- 显示内部组件 -->
              <component v-else :is="menu.component" :key="menu.id"></component>
            </template>
          </el-tab-pane>
        </el-tabs>
        <!-- tabs右键菜单 -->
        <ContextMenu ref="tabContextMenu" :visible="tabContextMenuVisible" :position="tabContextMenuPosition" :menuList="tabContextMenuList"></ContextMenu>
      </el-main>
    </el-container>
  </el-container>
</template>

<script>
import '@/assets/style/reset.css'

import Menu from '@/components/backstageManager/Menu';
import ContextMenu from '@/components/contextMenu/ContextMenu'
import leftMenu from '@/common/apiData/leftMenu.json';

export default {
  components: {
    Menu,
    ContextMenu
  },
  created () {
    window.onclick = () => {
      // 关闭tab右键菜单
      this.tabContextMenuVisible = false;
    }
  },
  data () {
    return {
      // 上方菜单选中的index
      topMenuActiveIndex: '',
      // 左侧菜单数据（扁平化）
      leftMenu: leftMenu,
      // 左边菜单选中的index
      leftMenuActiveIndex: '0',
      // 后台管理tab
      tabList: [
        {
          id: '0',
          name: '主页',
          routerPath: '/',
          closeable: false, // 该tab是否可以删除
          component: () => import(`@/views/backstageManager/BackstageManagerMain.vue`)
        }
      ],
      // 被选中的tab选项卡
      activeTabId: '0', //0为主页，默认选中主页
      // 唤醒右键菜单的tabId
      tabIdOfCallContextMenu: '',
      // 是否展示tab的右键菜单
      tabContextMenuVisible: false,
      // tab右键菜单在哪个位置显示
      tabContextMenuPosition: {
        top: 0,
        left: 0
      },
      tabContextMenuList: [
        {
          name: "刷新当前标签",
          method: () => {
            let tab = this.tabList.find(item => item.id == this.tabIdOfCallContextMenu);
            tab.reloading = true;
            setTimeout(() => {
              tab.reloading = false;
              this.$forceUpdate();
            }, 50)
            this.tabContextMenuVisible = false;
          }
        },
        {
          name: "关闭当前标签",
          method: () => {
            this.handleRemoveTab(this.tabIdOfCallContextMenu);
            this.tabContextMenuVisible = false;
          }
        },
        {
          name: "关闭左侧标签",
          method: () => {
            let newTabList = [];
            let index = this.tabList.findIndex(item => item.id == this.tabIdOfCallContextMenu);
            for (let i = 0; i < index; i++) {
              let tab = this.tabList[i];
              if (!tab.closeable) {
                newTabList.push(tab);
              }
            }
            for (let tab of this.tabList.slice(index)) {
              newTabList.push(tab);
            }
            // 关闭左侧的标签，会导致当前tab刷新 TODO
            this.tabList = newTabList;
            // 如果当前没有激活的菜单，则激活tabIdOfCallContextMenu
            if (-1 == this.tabList.findIndex(item => item.id == this.activeTabId)) {
              this.activeTabId = this.tabIdOfCallContextMenu
            }
            this.tabContextMenuVisible = false;
          }
        },
        {
          name: "关闭右边标签",
          method: () => {
            let index = this.tabList.findIndex(item => item.id == this.tabIdOfCallContextMenu);
            let newTabList = this.tabList.slice(0, index + 1);
            for (let i = index + 1, length = this.tabList.length; i < length; i++) {
              let tab = this.tabList[i];
              if (!tab.closeable) {
                newTabList.push(tab);
              }
            }
            this.tabList = newTabList;
            // 如果当前没有激活的菜单，则激活tabIdOfCallContextMenu
            if (-1 == this.tabList.findIndex(item => item.id == this.activeTabId)) {
              this.activeTabId = this.tabIdOfCallContextMenu
            }
            this.tabContextMenuVisible = false;
          }
        }
      ],
      // 导航面包屑
      breadcrumbList: [{ name: '主页' }],
    };
  },
  computed: {
    // 将扁平化的菜单数据 格式化成 树状的格式，并且加载component
    treeFormatLeftMenu () {
      let menuList = [];
      // 递归获取菜单下的菜单
      let getMenuListByParentId = (parentMenu) => {
        let subMenuList = this.leftMenu.filter(item => item.parentId == parentMenu.id);
        parentMenu.children = subMenuList;
        parentMenu.children.forEach(item => {
          // 如果当前菜单为文件夹类型，则获取子菜单
          if (item.isFolder) {
            getMenuListByParentId(item)
          }
          // 当前菜单为菜单类型
          else {
            // 外链
            if (item.url) {
              // 空实现
            }
            // 获取菜单对应的component
            else {
              getComponentByMenu(item);
            }
          }
        })
      }
      // 获取菜单对应的的component
      let routerOptionList = this.$router.options.routes; // 路由配置表
      let getComponentByMenu = (menu) => {
        let targetRouter = routerOptionList.find(routerOption => {
          if (menu.routerName) {
            return routerOption.name == menu.routerName
          } else if (menu.routerPath) {
            return routerOption.path == menu.routerPath
          }
          return false;
        });
        if (targetRouter) {
          menu.component = targetRouter.component;
        }
      }
      // 获取所有的根菜单
      let rootMenuList = this.leftMenu.filter(item => item.parentId == -1);
      rootMenuList.forEach(item => {
        if (item.isFolder) {
          // 如果当前菜单为文件夹类型，则获取子菜单
          getMenuListByParentId(item)
        } else {
          // 当前菜单为菜单类型，则获取菜单对应的component
          getComponentByMenu(item);
        }
        menuList.push(item);
      })
      return menuList;
    }
  },
  methods: {
    /**
     * 打开tab的右键菜单
     */
    openTabContextMenu (e) {
      if (e.srcElement.id) {
        this.tabIdOfCallContextMenu = e.srcElement.id.substring("tab-".length);
        this.tabContextMenuVisible = true;
        this.tabContextMenuPosition = {
          top: e.clientY + 10,
          left: e.clientX
        }
      }
    },
    /**
     * 处理顶部导航栏菜单item选中事件
     * @param key 被点击菜单的id
     * @param keyPath 被点击菜单的面包屑路径
     */
    handleTopMenuSelect (key, keyPath) {
      console.log(key, keyPath);
      // 切换默认主题
      if ("3-1" == key) {
        console.log(this, this.$api)
        this.changeTheme({ themeName: "default" });
      }
      // 切换深色主题
      else if ("3-2" == key) {
        this.changeTheme({ themeName: "dark" });
      }
    },
    // 处理左侧导航栏菜单item选中事件
    handleLeftMenuSelect (key, keyPath) {
      // 被点击的菜单
      let menu = this.leftMenu.find(item => item.id == key);
      menu.keyPath = keyPath; // 面包屑
      // 添加tab菜单
      this.addTabIfAbsent(menu);
    },
    // 根据菜单item新增tab，并且维护tabList
    addTabIfAbsent (menuItem) {
      // 在tabList已经存在该菜单
      let isExistMenuInTabList = this.tabList.findIndex(tab => tab.id == menuItem.id) != -1;
      // 在tabList不存在该菜单：往tabList push该菜单，激活tab选中效果，并切换路由
      if (!isExistMenuInTabList) {
        menuItem.closeable = true; // 该tab是否可以删除
        this.tabList.push(menuItem);
      }
      // 激活tab选中效果
      this.activeTabId = menuItem.id;
    },
    // 处理tab删除事件，如果删除的是当前激活的tab，则删除后激活旁边的tab；否则只删除当前的tab
    handleRemoveTab (targetTabId) {
      let tabList = this.tabList;
      let activeTabId = this.activeTabId;
      if (activeTabId === targetTabId) {
        tabList.forEach((tab, index) => {
          if (tab.id === targetTabId) {
            let nextTab = tabList[index + 1] || tabList[index - 1];
            if (nextTab) {
              activeTabId = nextTab.id;
            }
          }
        });
      }
      // TODO，关闭前面的页签，会导致后面页签刷新
      this.tabList = tabList.filter(tab => tab.id !== targetTabId);
      this.activeTabId = activeTabId;
    }
  },
  watch: {
    // 监听当前激活的activeTab，以更新面包屑 和 绑定左侧的菜单栏
    activeTabId: function (newValue, oldValue) {
      // 根据tabId获取菜单
      let activeMenu = this.leftMenu.find(menu => menu.id == newValue);
      // 更新面包屑
      this.breadcrumbList = activeMenu.keyPath.map(key => {
        return this.leftMenu.find(item => item.id == key);
      })
      // 更新左侧菜单选中效果
      this.leftMenuActiveIndex = activeMenu.id;
    },
    watch: {
      contextMenuVisible (value) {
        if (this.contextMenuVisible) {
          document.body.addEventListener("click", this.closeContextMenu);
        } else {
          document.body.removeEventListener("click", this.closeContextMenu);
        }
      }
    },
  }
}
</script>

<style lang="less" scoped>
#backstageManagerPage {
  height: 100%;
  #appTopHeader {
    padding: 0px;
    display: flex;
    .el-menu {
      flex-grow: 0;
    }
  }
  #appLogo {
    width: 200px;
    display: flex;
    justify-content: center;
    img {
      max-height: 100%;
      max-width: 100%;
    }
  }
  #topNavMenu {
    width: calc(100% - 200px);
  }
}

// 左侧菜单导航栏
section {
  max-height: calc(100% - 60px);
  #leftNavMenu {
    //   height: 100%;
    ul {
      height: 97%;
      border-bottom: 1px solid #dcdfe6;
      overflow-x: hidden;
    }
  }
}

#centerDiv {
  padding: 10px;
  // 面包屑
  #centerBreadcrumb {
    padding-bottom: 10px;
  }
  // 中间tab可视区域
  #centerTab {
    height: calc(100% - 30px);
    /* 第一个tab不能删除 */
    /deep/ .el-tabs__nav .el-tabs__item:nth-child(1) span {
      display: none;
    }
    // tab中间区域。因为是子组件里面的，所以需要deep
    /deep/ .el-tabs__content {
      height: calc(100% - 69px);
      padding: 0px;
      .el-tab-pane {
        height: 100%;
        overflow: auto;
        iframe {
          width: 100%;
          height: 100%;
          overflow: auto;
        }
      }
    }
  }
}
</style>
